module(..., package.seeall)
-- 必须在这个位置定义PROJECT和VERSION变量

-- PROJECT：ascii string类型，可以随便定义，只要不使用,就行
-- VERSION：ascii string类型，如果使用Luat物联云平台固件升级的功能，必须按照"X.X.X"定义，X表示1位数字；否则可随便定义

-- 加载日志功能模块，并且设置日志输出等级
-- 如果关闭调用log模块接口输出的日志，等级设置为log.LOG_SILENT即可
LOG_LEVEL = log.LOGLEVEL_TRACE
require "sys"
require "ril"
require "http"
require "httpTask"
require "mqttOutMsg"
-- require "mqttInMsgQuakeInfoRel"
require "log"
require "logGenerator"

-- 打印死机信息
ril.request("AT*EXINFO?")
rtos.sleep(3000)
-- 参数配置文件初始化
nvm.init("config.lua", true)

-- nvm.sett("securityConfig", 1, tostring(""), "SVR")   --"key"
-- nvm.sett("securityConfig", 3, tostring(""), "SVR")   --"cert"
-- nvm.sett("securityConfig", 5, tostring(""), "SVR")   --"token"
-- nvm.sett("securityConfig", 8, tostring(""), "SVR")   --"flagMqttConnect"

USER_DIR_PATH = "/user_dir"
-- nvm.sett("centerConfig", 6, "d7ff7da8-74fa-4aa7-9b50-c6cb125fb90a", "SVR")
local clientId = nvm.get("centerConfig")[6]
local username = nvm.get("centerConfig")[7]
-- clientId="d6ff7da8-74fa-4aa7-9b50-c6cb125fb90a"
-- clientId=nvm.get("centerConfig")[6]
-- username="test_username"
local clientNo = nvm.get("info")[1]
local handle = dl.open("/lua/dzjkxc.lib", "dzjkxc_main")
local baseUrl = "https://api-sit.isignet.cn:8082/cert/v2"
-- local baseUrl="http://148.135.118.201:1234/cert/v2"
-- nvm.sett("securityConfig", 2, "", "SVR")

-- local secret = "y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA"
local secret = nvm.get("securityConfig")[6]
if secret == "" then
    nvm.sett("securityConfig", 6, "y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA", "SVR")
end
log.info("nvm secret value:", secret)

local keyData = nvm.get("securityConfig")[1]
local paraKey -- = nvm.get("securityConfig")[2]
local csrr
CertData = nvm.get("securityConfig")[3]
log.info("nvm CertData value:", CertData)
CertSn = ""
ServerCA = ""
local fileOfficialCA = "/lua/ca.b64.cer"
local fileServerCA = "/lua/server.ca"

function stringToBool(str)
    str = tostring(str)
    return (str == "true")
end

TokenData = nvm.get("securityConfig")[5]
log.info("nvm TokenData value:", TokenData)

FlagUseToken = stringToBool(nvm.get("centerConfig")[21])
log.info("FlagUseToken:", FlagUseToken)
local authServer = nvm.get("centerConfig")[22]
log.info("auth server:", authServer)

local mckParams, caParams = nvm.get("centerConfig")[23],
                            nvm.get("centerConfig")[24]
local previousMckParams, previousCaParams = nvm.get("securityConfig")[8],
                                            nvm.get("securityConfig")[9]
local previousAuthServer = nvm.get("securityConfig")[10]
local mckServer = ""
local mckServerFQDN = ""
local mckPort = 9080
local mckAppId = ""
local mckAppSecret = ""

local caBaseUrl = ""
local caDeviceId = ""
local caAppId = ""
local caSecret = ""

local logInfo, errorInfo, sysTime = "", "", ""

local IPType = {[0] = "Error", "IPv4", "IPv6", "Domain", "string"}
local R = {ERROR = 0, IPV4 = 1, IPV6 = 2, STRING = 3, string=4}

function GetIPType(ip)
  if type(ip) ~= "string" then log.info("input parameter is not string format.") end

  -- check for format 1.11.111.111 for ipv4
  local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")}
  if #chunks == 4 then
    for _,v in pairs(chunks) do
      if tonumber(v) > 255 then return false end
    end
    return true
  end

  -- check for ipv6 format, should be 8 'chunks' of numbers/letters
  -- without leading/trailing chars
  -- or fewer than 8 chunks, but with only one `::` group
  local chunks = {ip:match("^"..(("([a-fA-F0-9]*):"):rep(8):gsub(":$","$")))}
  if #chunks == 8
  or #chunks < 8 and ip:match('::') and not ip:gsub("::","",1):match('::') then
    for _,v in pairs(chunks) do
      if #v > 0 and tonumber(v, 16) > 65535 then return false end
    end
    return true
  end

end

local function serverIsIP()
    local IPType = {[0] = "Error", "IPv4", "IPv6", "string"}
    local ips = {
        "128.1.0.1", -- ipv4
        "223.255.254.254", -- ipv4
        "999.12345.0.0001", -- invalid ipv4
        "1050:0:0:0:5:600:300c:326b", -- ipv6
        "1050!0!0+0-5@600$300c#326b", -- string
        "1050:0:0:0:5:600:300c:326babcdef", -- string
        "1050:0000:0000:0000:0005:0600:300c:326b", -- ipv6
        "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", -- ipv6
        "fe80:0:0:0:202:b3ff:fe1e:8329", -- ipv6
        "fe80::202:b3ff:fe1e:8329", -- ipv6
        "1050:::600:5:1000::", -- contracted ipv6
        "::", -- ipv6
        "::1", -- ipv6
        "::1::", -- string
        "129.garbage.9.1", -- string
        "xxx127.0.0.0", -- error
        "xxx1050:0000:0000:0000:0005:0600:300c:326b", -- string
        "fcg.earthquake.cn", --string
        -- 129.10 -- error
    }
    for k,v in pairs(ips) do
        local temp=GetIPType(v)
        if temp~=nil then
            print(v, temp)
        end

    end

    -- log.info("IP type is:"..GetIPType("128.1.0.1"))

end

local function judgeMckCaparams()
    if previousMckParams ~= mckParams or previousCaParams ~= caParams then
        log.info("mckPara or caPara get updated!")
        nvm.sett("securityConfig", 1, tostring(""), "SVR") -- "key"
        nvm.sett("securityConfig", 3, tostring(""), "SVR") -- "cert"
        nvm.sett("securityConfig", 5, tostring(""), "SVR") -- "token"
        -- nvm.sett("securityConfig", 8, tostring(""), "SVR") -- "flagMqttConnect"
        previousMckParams = mckParams
        previousCaParams = caParams
        nvm.sett("securityConfig", 8, tostring(previousMckParams), "SVR")
        nvm.sett("securityConfig", 9, tostring(previousCaParams), "SVR")

    end

end
if FlagUseToken == true then judgeMckCaparams() end

local function configMCK()
    local mck_server = ""
    if mckServer ~= "" then mck_server = mckServer end
    -- mck_server = "222.128.62.153" -- TODO use this for DT zfh
    -- local mck_server = tostring(authServer)
    local mck_port = ""
    if mckPort ~= "" then mck_port = mckPort end
    -- mck_port = 19527  --TODO use this for DT

    local mck_appid = ""
    if mckAppId ~= "" then mck_appid = mckAppId end
    -- mck_appid = "XZGw9Vcbeb389c43ca47"  --TODO use this for DT

    local mck_appsecret = ""
    if mckAppSecret ~= "" then mck_appsecret = mckAppSecret end
    -- mck_appsecret = "6bd37a9c91dd45ae90a4ab51f00c04ecd93cb46dcaf649709d48023a35dbdaba"  --TODO use this for DT
    if handle then
        local ret = dzjkxc.set_mck_conf(mck_server, mck_port, mck_appid,
                                        mck_appsecret)
        print("SetMckConf: ret = ", ret)
    end
end
-- configMCK()

local function getIPCbFnc(result, prompt, head, body)
    log.info("testHttp.cbFnc-getIPCbFnc", result, prompt)
    if result and head then
        for k, v in pairs(head) do
            log.info("testHttp.cbFnc", k .. ": " .. v)
        end
    end
    if result and body then
        -- log.info("testHttp.cbFnc","bodyLen="..body:len())
        -- log.info("body:", body)
        -- log.info("body type:",type(body))
        local tjsondata, resultBody, errinfo = json.decode(body)
        -- log.info("tjsondata_result", resultBody)
        -- log.info("tjsondata_rrinfo", errinfo)
        -- log.info("tjsondata of getip:",tjsondata,"type of tjsondata:",type(tjsondata))
        -- if mckServer == "" or mckServer == nil and tjsondata[1] ~= "" then
        if tjsondata[1] ~= "" then
            mckServer = tostring(tjsondata[1])
            log.info("the mckServer Ip is1:", mckServer, tjsondata[1])
            if mckServer ~= "" then
                -- nvm.sett("securityConfig", 8, tostring(mckServer), "SVR")
                log.info("the mckServer para is:", mckServer, mckPort, mckAppId,
                         mckAppSecret)
                configMCK()
            end

        end

        log.info("the mckServer Ip is2:", mckServer, tjsondata[1])
        log.info("the mckServer para is:", mckServer, mckPort, mckAppId,
                 mckAppSecret)
        -- sys.publish("MCK_SERVER_IP_GOT")
        -- if tjsondata["status"]== 200 and tjsondata["message"]=="SUCCESS" then
        --     CertData = tostring(tjsondata["data"]["cert"])           --need save to flash
        --     CertSn = tostring(tjsondata["data"]["certSn"])
        --     nvm.sett("securityConfig", 3, tostring(CertData), "SVR")
        --     nvm.sett("securityConfig", 4, tostring(CertSn), "SVR")
        -- end

    end
end

local function strToArr(str)

    local arr = {}
    if str ~= "" and str ~= nil then
        -- 将字符串转换为数组
        for word in string.gmatch(str, "([^,]+)") do
            table.insert(arr, word)
        end

        -- 输出数组
        for i, v in ipairs(arr) do print(i, v) end
    end
    return arr
end

local function getParams()
    local arr = {}
    if mckParams ~= "" and mckParams ~= nil then
        -- 将字符串转换为数组
        arr = strToArr(mckParams)
    end
    mckServerFQDN = arr[1]
    mckPort = arr[2]
    mckAppId = arr[3]
    mckAppSecret = arr[4]

    log.info("the mckServer para setting on webpage is:", mckServerFQDN, mckPort, mckAppId,
             mckAppSecret)

    log.info("mckParams:", mckParams)
    log.info("arr params:", arr[1], arr[2], arr[3], arr[4])



    local res=GetIPType(mckServerFQDN)
    if res==true then

        mckServer=mckServerFQDN
        log.info("the para is IPv4:"..mckServer)
        configMCK()
    else
        log.info("the para is dns:"..mckServerFQDN)
        local url = "http://223.5.5.5/resolve?short=1&name=" ..
        tostring(mckServerFQDN)

        log.info("to resolve url:", url)

        local resp = http.request("GET", url, nil, {
        ["Accept"] = "*/*",
        ["Content-Type"] = "application/json"
        }, nil, 30000, getIPCbFnc)
        -- sys.waitUntil("MCK_SERVER_IP_GOT",3000)
        log.info("http get resp:", resp)

    end


    -- while mckServer=="" or mckServer==nil do
    --     mckServer=nvm.get("securityConfig")[8]
    --     log.info("the mckServer Ip is 1:",mckServer)
    -- end
    -- mckServer=nvm.get("securityConfig")[8]
    -- log.info("the mckServer Ip is3:",mckServer)
    -- mckServer=nvm.get("securityConfig")[8]
    -- if mckServer=="" or then
    --     wait()
    -- end

    if caParams ~= "" and caParams ~= nil then
        -- 将字符串转换为数组
        arr = strToArr(caParams)
        caBaseUrl = arr[1]
        caDeviceId = arr[2]
        -- caDeviceId="DEV_B90213F1BAD64B7AA139724161E3B339"   --TODO use this for DT
        caAppId = arr[3]
        -- caAppId="67f6c99b74484c2b8bcb35473850cdd7"   --TODO use this for DT
        caSecret = arr[4]
        -- caSecret="MBxCw0HP7kEVhvC5QL4Da74gzDL7chfU"    --TODO use this for DT
    end
    log.info("the ca para is:", caBaseUrl, caDeviceId, caAppId, caSecret)

end

if FlagUseToken == true then getParams() end

FlagMqttConnect = true --stringToBool(nvm.get("securityConfig")[7])
log.info("type of FlagMqttConnect:", FlagMqttConnect, type(FlagMqttConnect))

local connect_times = 0
local maxConnectTimes = 5
-- clientNo="xx0000000123"
local signature = ""

local function init()
    if handle then
        if keyData == "" or keyData == nil then
            log.info("request keydata in init")
            local data, key, ret = dzjkxc.get_key("", clientId)
            log.info("GetKey: !!keyData!! = ", keyData)
            log.info("        key = ", key)
            log.info("        ret = ", ret)
            if ret == "0" or ret == 0 then
                log.info("generate new key in init()")
                nvm.sett("securityConfig", 1, tostring(data), "SVR")
                -- nvm.sett("securityConfig", 2, tostring(key), "SVR")
            end
        end
        keyData = nvm.get("securityConfig")[1]
        -- paraKey = nvm.get("securityConfig")[2]
        log.info("nvm keyData value in init:", keyData)
        -- log.info("nvm paraKey value:",paraKey)
    end
end
init()

-- if type(rtos.openSoftDog)=="function" then
--     rtos.openSoftDog(50000)
--     sys.timerLoopStart(rtos.eatSoftDog,3000)
-- end
--[[
dl模块接口定义
函数：handle=dl.open(libpath,usermap)
功能：加载c编译的lib文件
  参数：
      --path:lib的路径,string类型
      --usermap:lua函数接口注册表
  返回值：
      --handle:成功返回句柄，失败返回nil

  函数： ret = dl.close(handle)
  功能：卸载lib
      参数：
          handle:dl.open的返回值
      返回值：nil
]]

local function reqMarkCertCbFnc(result, prompt, head, body)
    log.info("testHttp.cbFnc-reqMarkCertCbFnc", result, prompt)
    if result and head then
        for k, v in pairs(head) do
            log.info("testHttp.cbFnc", k .. ": " .. v)
        end
    end
    if result and body then
        log.info("testHttp.cbFnc", "bodyLen=" .. body:len())
        log.info("get cert body is:", body)
        log.info("body type:", type(body))
        local tjsondata, resultBody, errinfo = json.decode(body)
        log.info("tjsondata_result", resultBody)
        log.info("tjsondata_rrinfo", errinfo)
        log.info("tjsondata:", tjsondata, "type of tjsondata:", type(tjsondata))
        if tjsondata["status"] == 200 and tjsondata["message"] == "SUCCESS" then
            CertData = tostring(tjsondata["data"]["cert"]) -- need save to flash
            CertSn = tostring(tjsondata["data"]["certSn"])
            nvm.sett("securityConfig", 3, tostring(CertData), "SVR")
            nvm.sett("securityConfig", 4, tostring(CertSn), "SVR")

            -- else
            --     -- CertData=""
            --     -- CertSn=""

        end

        log.info("cert data:", CertData)
        log.info("certSn data:", CertSn)

    end
end

local function generateSignString(props)

    local str = ""
    local list = {}
    jsonTable = props
    local length = 0
    log.info(jsonTable["id"], ":", jsonTable["name"])
    for k, v in pairs(jsonTable) do
        length = length + 1
        print(k, v)
        list[length] = k
    end

    table.sort(list)

    -- 打印排序后的数组
    for i = 1, #list do
        -- print(list[i])
        key = list[i]
        value = jsonTable[list[i]]
        print(key, value)

        if value == nil or value == "null" or "signature" == key then
            log.info("value is nil or key is signature:", i, key, value)
        else
            if i == #list then
                log.info("postion of last value:", i, key, value)
                str = str .. key .. "=" .. value
            else
                log.info("other element:", i, key, value)
                str = str .. key .. "=" .. value .. "&"
            end

        end

    end

    -- print("JSON length:", length)
    return str
end

local function getHMAC(data, key, HmacAlgo)
    -- SecretKeySpec signingKey = new SecretKeySpec(key, HmacAlgo);
    -- Mac mac = Mac.getInstance(HmacAlgo);
    -- mac.init(signingKey);
    -- return base64Encode(mac.doFinal(data));

end

local function tableToJson(tbl)
    local jsonString = "{"
    for k, v in pairs(tbl) do
        if type(k) == "string" then
            jsonString = jsonString .. '"' .. k .. '":'
        end
        if type(v) == "table" then
            jsonString = jsonString .. tableToJson(v)
        elseif type(v) == "string" then
            jsonString = jsonString .. '"' .. v .. '",'
        else
            jsonString = jsonString .. tostring(v) .. ','
        end
    end
    jsonString = string.sub(jsonString, 1, -2) .. "}"
    return jsonString
end

local function generateRequestJson(request, key)
    local data = generateSignString(request)
    -- data="appId=APP_D_8FF38202E7A444E1B04EB481D00772D1&certExpire=1825&certReq=MIICkzCCAXsCAQAwTjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAmFhMQswCQYDVQQHDAJhYTELMAkGA1UECgwCYWExCzAJBgNVBAsMAmFhMQswCQYDVQQDDAJhYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMFXFsAZGPgJJ2MXPQbcGO0ysziBfJst4yOPnjNt8VuUOq3WcUcQ2eZJpnL3W4Oq1LS1jhUp+f2w92Ny2yTJxuO9xSDNbaStzbn5w94kv3rZg4ywlTiMJnMtU5V6otWc6g+WCKpw7wObNF8/7PSJVfYGxxsZdNsCEjG1Q70OqpdCsIExZBtoMh6Hi28ULNCEZ0mMbr1gn5twyfv/DokSzmB/+NJ4A4KlOIiHQCMaq/SRnTRBkxaBVCu7BhTh3+PDeMkJh8yhf7kvIUEoDxNpG2+iGcHQPcKw7WHK7g6cz1gekRLskBOAuCwlNmLefzZrRJBB4PxEBwLjQZt4SIORqCcCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQARcJNNEh6e+fDPVWKT1RxmtN7XMi2XoUTeoRQ7LgjVd5TUkuo6/UpwIzgekLDpzsMlFQVUMvIKfCIAbXmC3RhsoyzxFJlyRSiWTTDXumpuD1Y7BN1SJaCw/mTsTTrFwNkrUZIloHpDMgTcQZ+yd11lWfsIxxyhmsUjkbUQglmCtbFi3WCMNpx68FH1IchOjBH0lawsP0qH+Bo6RwHWUNSXGeTU185KZUHU/NMuAhn2w4SzmzdctLvUXb4DPBN0/nH2mmLb3l7gpXxFioUU8j5tDVrADtP2ThM+lWL6od5JCI3Zuauivqt0t6rbRECBvep4uRXDC6Q2odMGym2ACeUs&certTemplateId=UTRUST_COMMON_SM2_SINGLE&deviceId=DEV_D_CC03AB7B11734B758AAD86E22EE00B63&signAlgo=HMAC&userMark=aa&version=1.0"
    log.info("concate string data: ", data)
    local paraTable_head = "{"
    local paraTable_tail = "}"
    local paraTable
    local length = 0
    local size = 0
    -- String data = generateSignString(request);
    -- String signature;
    -- signature = getHMAC(data.getBytes(), key.getBytes(), "HmacSHA256");
    -- local signature =
    local mac, rv = dzjkxc.hmac_sha256_b64(data, key) -- 返回的mac已经做了base64编码，message和secret都是字符串形式，不经过base64编码
    -- local mac, rv = dzjkxc.hmac_sha256_b64("y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA", "y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA")
    log.info("mac:", mac, "rv:", rv)

    -- request.put("signature", signature);
    request["signature"] = mac

    for k, v in pairs(request) do size = size + 1 end
    log.info("table size=", size)
    paraTable = paraTable_head
    for k, v in pairs(request) do
        length = length + 1
        print(k, v, length)
        if length == size then
            paraTable = paraTable .. '["' .. k .. '"] = "' .. v .. '"'
        else
            paraTable = paraTable .. '["' .. k .. '"] = "' .. v .. '",'
        end
    end
    paraTable = paraTable .. paraTable_tail
    local body = {
        ["appId"] = request["appId"],
        ["deviceId"] = request["deviceId"],
        ["signAlgo"] = request["signAlgo"],
        ["version"] = request["version"],
        ["userMark"] = request["userMark"],
        ["certTemplateId"] = request["certTemplateId"],
        ["signature"] = request["signature"],
        ["certExpire"] = request["certExpire"],
        ["certReq"] = request["certReq"]
    }
    -- log.info("++++++++++++++++++++++++typeof body+++++++++++++++++++++++",type(body))

    log.info("paraTable:", paraTable)
    -- return new GsonBuilder().disableHtmlEscaping().create().toJson(request);
    local jsonString = tableToJson(body)
    log.info("jsonString:", jsonString)

    -- local ret=request
    -- print("ret-ret:",tostring(ret))
    return jsonString
end

-- 申请标识证书
local function reqMarkCert()
    local data, key, ret
    local map = {}
    map["appId"] = "APP_D_8FF38202E7A444E1B04EB481D00772D1"
    map["deviceId"] = "DEV_D_CC03AB7B11734B758AAD86E22EE00B63"
    map["signAlgo"] = "HMAC"
    map["version"] = "1.0"
    map["userMark"] = clientId -- 用户标识

    -- log.info("clientNo:",clientNo)

    -- local mck_server = "222.128.62.153"
    -- local mck_port = 19527
    -- local mck_appid = "XZGw9Vcbeb389c43ca47"
    -- local mck_appsecret =
    --     "6bd37a9c91dd45ae90a4ab51f00c04ecd93cb46dcaf649709d48023a35dbdaba"
    -- local ret = dzjkxc.set_mck_conf(mck_server, mck_port, mck_appid,
    --                                 mck_appsecret)
    -- print("SetMckConf: ret = ", ret)
    keyData = nvm.get("securityConfig")[1]
    -- paraKey = nvm.get("securityConfig")[2]
    log.info("nvm keyData value in reqMarkCert 1:", keyData)
    -- log.info("nvm paraKey value:",paraKey)

    if keyData == "" or keyData == nil then
        log.info("request keydata in reqMarkcert--1")

        -- 次数限制
        log.info("generate new key")
        data, key, ret = dzjkxc.get_key("", clientId)
        -- local data=" {"s":"222.128.62.153","p":19527,"a":"XZGw9Vcbeb389c43ca47","t":"6bd37a9c91dd45ae90a4ab51f00c04ecd93cb46dcaf649709d48023a35dbdaba","k":"27877","u":"E7m2Q2qqP/yMosg79JENYf1ZIMTVs8RVNU/5+3mtR8qKjN5E4xKZpkdmt9WcD31jSZIcETMvqXMvxjepxYafqA==","v":"JoAIl93BZWXyqQPHYl/C8k0uiwFWeY1MQbtNDwYQrGI="}"
        -- local key="userdata: 0x80c15248"
        log.info("GetKey: data === ", data)
        log.info("        key === ", key)
        log.info("        ret === ", ret)
        -- if data~="" then

        if ret == "0" or ret == 0 then
            paraKey = key
            nvm.sett("securityConfig", 1, tostring(data), "SVR")
            -- nvm.sett("securityConfig", 2, tostring(key), "SVR")
        end
    else
        log.info("request keydata in reqMarkcert--2")
        data, key, ret = dzjkxc.get_key(tostring(keyData), clientId)
        if ret == "0" or ret == 0 then
            paraKey = key
            log.info("nvm keyData value in reqMarkCert 2:", data)
            -- nvm.sett("securityConfig", 1, tostring(data), "SVR")
            -- nvm.sett("securityConfig", 2, tostring(key), "SVR")
        end
    end
    -- keyData=data

    -- log.info("keyData in loop--:",keyData)

    keyData = nvm.get("securityConfig")[1]
    -- paraKey = nvm.get("securityConfig")[2]
    log.info("nvm keyData value in reqMarkCert 3:", keyData)
    -- log.info("nvm paraKey value:",paraKey)

    if paraKey ~= "" and clientId ~= "" and username ~= "" then
        log.info("paraKey:", paraKey)
        log.info("clientId:", clientId)
        log.info("username:", username)
        log.info("GenerateCsr:--1")
        log.info("generate new csr")
        local csr, ret = dzjkxc.generate_csr(paraKey, tostring(clientId),
                                             tostring(username)) -- paraKey参数不能用tostring()
        -- local csr, ret = dzjkxc.generate_csr(paraKey, "device_clientid", "device_username")
        log.info("GenerateCsr: csr = ", csr)
        log.info("GenerateCsr: ret = ", ret)
        csrr = csr
    end

    map["certReq"] = csrr
    map["certTemplateId"] = "UTRUST_COMMON_SM2_SINGLE" -- 证书模板id
    map["certExpire"] = "1825"; -- 有效期 非必传
    -- map["certExt"]= "[{\"oid\": \"1.2.156.10260.4.1.1\", \"oidValue\": \"1111111111\"}]" -- 证书扩展项  非必传
    local requestJson = generateRequestJson(map, secret)
    log.info("requestJson:", tostring(requestJson), "typeof requestJson:",
             type(requestJson))
    local url = baseUrl .. "/markCert/reqMarkCert"
    log.info("request url=", url)
    -- 次数限制
    if CertData == "" or CertData == nil then
        log.info("redo request cert operation.")
        log.info("generate new cert")
        local resp = http.request("POST", url, nil, {
            ["Accept"] = "*/*",
            ["Content-Type"] = "application/json"
        }, requestJson, 30000, reqMarkCertCbFnc);
        log.info("http post resp:", resp);
    end

    -- sys.wait(3000)
    CertData = nvm.get("securityConfig")[3]
    log.info("certData is: ", CertData)
    log.info("paraKey is: ", paraKey)
    local rt = os.time()
    log.info("time stamp is:", rt)
    if TokenData == "" or TokenData == nil then
        if paraKey ~= "" and rt ~= "" and CertData ~= "" then
            log.info("generate new token")
            -- local token, ret = dzjkxc.generate_token(paraKey, rt,
            -- "222.128.62.153", CertData)
            local token, ret = dzjkxc.generate_token(paraKey, rt,
                                                     tostring(authServer),
                                                     CertData)

            print("GenerateToken: token = ", token)
            print("GenerateToken: ret = ", ret)
            if ret == "0" or ret == 0 then
                nvm.sett("securityConfig", 5, tostring(token), "SVR")
            end
        end

    end
    TokenData = nvm.get("securityConfig")[5]
    log.info("tokenData is:", TokenData)

end

local function updateMarkCertCbFnc(result, prompt, head, body)
    log.info("testHttp.cbFnc", result, prompt)
    if result and head then
        for k, v in pairs(head) do
            log.info("testHttp.cbFnc", k .. ": " .. v)
        end
    end
    if result and body then
        log.info("testHttp.cbFnc", "bodyLen=" .. body:len())
        log.info("body:", body)
        log.info("body type:", type(body))
        local tjsondata, resultBody, errinfo = json.decode(body)
        log.info("tjsondata_result", resultBody)
        log.info("tjsondata_rrinfo", errinfo)
        log.info("updateMarkCert tjsondata:", tjsondata, "type of tjsondata:",
                 type(tjsondata))
        if tjsondata["status"] == 200 and tjsondata["message"] == "SUCCESS" then
            -- certData = tostring(tjsondata["data"]["cert"])
            -- certSn = tostring(tjsondata["data"]["certSn"])

        else
            -- certData=""
            -- certSn=""

        end

        -- log.info("cert data:",certData)
        -- log.info("certSn data:",certSn)

    end
end

-- 更新标识证书
local function updateMarkCert()
    local map = {}
    map["appId"] = "APP_D_8FF38202E7A444E1B04EB481D00772D1"
    map["deviceId"] = "DEV_D_CC03AB7B11734B758AAD86E22EE00B63"
    map["signAlgo"] = "HMAC"
    map["version"] = "1.0"
    map["userMark"] = clientId -- 用户标识
    map["certReq"] = csrr
    map["certTemplateId"] = "UTRUST_COMMON_SM2_SINGLE" -- 证书模板id
    map["certExpire"] = "1825" -- 有效期 非必传
    map["certSn"] = CertSn -- 证书序列号

    local requestJson = generateRequestJson(map, secret)
    log.info("requestJson:", tostring(requestJson), "typeof requestJson:",
             type(requestJson))
    local url = baseUrl .. "/markCert/updateMarkCert"
    log.info("request url=", url)
    local resp = http.request("POST", url, nil, {
        ["Accept"] = "*/*",
        ["Content-Type"] = "application/json"
    }, requestJson, nil, updateMarkCertCbFnc);
    log.info("http post resp:", resp);

end

-- 函数调用目的：产生paraKey
local function refreshKey()
    local data, key, ret
    sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                os.date("*t").year, os.date("*t").month,
                                os.date("*t").day, os.date("*t").hour,
                                os.date("*t").min, os.date("*t").sec)
    keyData = nvm.get("securityConfig")[1]
    log.info("nvm keyData value in refreshKey 1:", keyData)
    if keyData == "" or keyData == nil then
        -- log.info("request keydata in refreshKey--1")

        -- 次数限制
        if handle then
            log.info("generate new key in refreshKey")
            data, key, ret = dzjkxc.get_key("", clientId)
        end

        if ret == "0" or ret == 0 then
            paraKey = key
            log.info("nvm keyData value in refreshKey 2:", paraKey)
            nvm.sett("securityConfig", 1, tostring(data), "SVR")
            logInfo = "[" .. sysTime .. "]" .."[key:"..data..  ",paraKey:"..tostring(paraKey).."]\n"
            logGenerator.generateLogTask(logInfo, "log")
            -- nvm.sett("securityConfig", 2, tostring(key), "SVR")
        end
    else
        -- log.info("request keydata in refreshKey--2")
        if handle then
            data, key, ret = dzjkxc.get_key(tostring(keyData), clientId)
        end

        if ret == "0" or ret == 0 then
            paraKey = key
            log.info("nvm keyData value in refreshKey 3:", paraKey)
            logInfo = "[" .. sysTime .. "]" .."[key:"..keyData..",paraKey:"..tostring(paraKey).."]\n"
            logGenerator.generateLogTask(logInfo, "log")
            -- nvm.sett("securityConfig", 1, tostring(data), "SVR")
            -- nvm.sett("securityConfig", 2, tostring(key), "SVR")
        end
    end

end

local function refreshCsr()
    sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                os.date("*t").year, os.date("*t").month,
                                os.date("*t").day, os.date("*t").hour,
                                os.date("*t").min, os.date("*t").sec)
    local csr, ret
    if paraKey ~= "" and clientId ~= "" and username ~= "" then
        log.info("paraKey:", paraKey)
        log.info("clientId:", clientId)
        log.info("username:", username)
        if handle then
            log.info("generate new csr")
            csr, ret = dzjkxc.generate_csr(paraKey, tostring(clientId),
                                           tostring(username)) -- paraKey参数不能用tostring()
        end
        -- local csr, ret = dzjkxc.generate_csr(paraKey, "device_clientid", "device_username")
        log.info("GenerateCsr: csr = ", csr)
        log.info("GenerateCsr: ret = ", ret)
        csrr = csr
    end
    logInfo = "[" .. sysTime .. "]" .."[csr:"..csr.."]\n"
    logGenerator.generateLogTask(logInfo, "log")
end

local function refreshCert()
    local map = {}
    log.info("the ca para is:", caBaseUrl, caDeviceId, caAppId, caSecret)
    if caAppId ~= "" then map["appId"] = caAppId end
    log.info("generate cert para-appId:", map["appId"])
    if caDeviceId ~= "" then map["deviceId"] = caDeviceId end
    log.info("generate cert para-deviceId:", map["deviceId"])
    local secret = ""
    if caSecret ~= "" then secret = caSecret end
    log.info("generate cert para-secret:", secret)
    -- map["appId"]="APP_D_8FF38202E7A444E1B04EB481D00772D1"
    -- map["deviceId"]="DEV_D_CC03AB7B11734B758AAD86E22EE00B63"
    map["signAlgo"] = "HMAC"
    log.info("generate cert para-signAlgo:", map["signAlgo"])
    map["version"] = "1.0"
    log.info("generate cert para-version:", map["version"])
    map["userMark"] = clientId -- 用户标识
    log.info("generate cert para-userMark:", map["userMark"])
    map["certReq"] = csrr
    log.info("generate cert para-certReq:", map["certReq"])
    map["certTemplateId"] = "UTRUST_COMMON_SM2_SINGLE" -- 证书模板id
    log.info("generate cert para-certTemplateId:", map["certTemplateId"])
    map["certExpire"] = "1825"; -- 有效期 非必传
    log.info("generate cert para-certExpire:", map["certExpire"])
    -- map["certExt"]= "[{\"oid\": \"1.2.156.10260.4.1.1\", \"oidValue\": \"1111111111\"}]" -- 证书扩展项  非必传
    local requestJson = generateRequestJson(map, secret) -- secret=y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA
    log.info("requestJson:", tostring(requestJson), "typeof requestJson:",
             type(requestJson))
    local url
    if caBaseUrl ~= "" then url = caBaseUrl .. "/markCert/reqMarkCert" end
    log.info("request url=", url)
    -- 次数限制
    CertData = nvm.get("securityConfig")[3]
    log.info("nvm cert data is:", CertData)
    if CertData == "" or CertData == nil then
        log.info("redo request cert operation.")
        log.info("generate new cert")
        log.info("URL11", url)
        local resp = http.request("POST", url, nil, {
            ["Accept"] = "*/*",
            ["Content-Type"] = "application/json"
        }, requestJson, 30000, reqMarkCertCbFnc)
        log.info("http post resp:", resp)
    end
end

local function refreshToken()
    sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                os.date("*t").year, os.date("*t").month,
                                os.date("*t").day, os.date("*t").hour,
                                os.date("*t").min, os.date("*t").sec)
    keyData = nvm.get("securityConfig")[1]
    -- local data, key, ret = dzjkxc.get_key(tostring(keyData), clientId)
    -- if ret=="0" or ret==0 then
    --     paraKey=key
    --     log.info("nvm keyData value in reqMarkCert 2:",data)
    -- end

    refreshKey()
    -- if keyData=="" or keyData==nil then
    --     refreshKey()
    -- end

    log.info("paraKey is: ", paraKey)
    -- logInfo = "[" .. sysTime .. "]" .."[paraKey:"..paraKey.."]\n"
    -- logGenerator.generateLogTask(logInfo, "log")

    CertData = nvm.get("securityConfig")[3]
    if CertData == "" or CertData == nil then
        refreshCsr() -- TODO 如果CertData存在了，就不需要重新生成csr
        refreshCert()
    end

    CertData = nvm.get("securityConfig")[3]
    -- log.info("certData is: ", CertData)
    logInfo = "[" .. sysTime .. "]" .."[CertData:"..CertData.."]\n"
    logGenerator.generateLogTask(logInfo, "log")
    -- TokenData = nvm.get("securityConfig")[5]
    local rt = os.time()
    log.info("time stamp is:", rt)
    if TokenData == "" or TokenData == nil or FlagMqttConnect == false then
        if paraKey ~= "" and rt ~= "" and CertData ~= "" then

            log.info("generate new token")
            local mck_server = ""
            if mckServer ~= "" then mck_server = mckServer end
            -- mck_server = "222.128.62.153" -- TODO use this for DT zfh
            local token, ret = dzjkxc.generate_token(paraKey, rt, mck_server,
                                                     CertData)
            -- local token, ret = dzjkxc.generate_token(paraKey, rt,
            -- tostring(authServer), CertData)

            -- print("GenerateToken: token = ", token)
            -- print("GenerateToken: ret = ", ret)
            if ret == "0" or ret == 0 then
                -- TokenData=token
                nvm.sett("securityConfig", 5, tostring(token), "SVR")
            end
        end

    end
    TokenData = nvm.get("securityConfig")[5]
    -- log.info("tokenData is:", TokenData)
    sys.publish("GENERATE_TOKEN_DONE")
    logInfo = "[" .. sysTime .. "]" .."[TokenData:"..TokenData.."]\n"
    logGenerator.generateLogTask(logInfo, "log")
end

local function saveServerCA(content)
    local cacert
    -- local cacert =
    --     "MIIClzCCAjygAwIBAgIQdd/IVUqMA6s1z1nouGE7njAMBggqgRzPVQGDdQUAMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4XDTEzMDExNjExMDczMVoXDTMzMDExMTExMDczMVowRDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBEJKQ0ExDTALBgNVBAsMBEJKQ0ExFzAVBgNVBAMMDkJlaWppbmcgU00yIENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEioqqRw0qmjPYUF+6SWgWI1JzDHPGO0iTjSa5m0MuR/QB83yLBknccZ3T1qwdgv27e3qqKMdA3U3ipZkz6qxVk6OCASIwggEeMB8GA1UdIwQYMBaAFEwysZfZMxvEpgXBxuWLYlvwl3ZYMA8GA1UdEwEB/wQFMAMBAf8wgboGA1UdHwSBsjCBrzBBoD+gPaQ7MDkxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoGA1UECwwDQVJMMQwwCgYDVQQDDANhcmwwKqAooCaGJGh0dHA6Ly93d3cucm9vdGNhLmdvdi5jbi9hcmwvYXJsLmNybDA+oDygOoY4bGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjozODkvQ049YXJsLE9VPUFSTCxPPU5SQ0FDLEM9Q04wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQf5s/Uj8UiKpdKKYoV5xbJkjTEtjAMBggqgRzPVQGDdQUAA0cAMEQCIFiMoH1BR7I3DmlPk5uhui/W2cX6iPAdnXI4LSPUg9T9AiB06XDp+wsPScMBYzRuY5xBC7IiC+nj+ehMDmkLD4mXKg=="
    if content ~= "" then cacert = content end

    log.info("cacert in saveServerCA:", cacert)

    -- local fileName="/lua/ca_test.b64.cer"
    local fileName = fileServerCA
    io.writeFile(fileName, tostring(cacert))
    -- if io.exists(fileName) then
    --     log.info("testFs.exists")
    --     io.writeFile(fileName,tostring(cacert))
    --     local fileval = io.readFile(fileName)
    --     log.info("testFs.readFile ",fileval)
    --     local filelen = io.fileSize(fileName)
    --     log.info("testFs.fileSize ",filelen)
    --     local fileinfo = io.pathInfo(fileName)
    --     log.info("testFs.pathInfo","dirname:",fileinfo.dirname,"filename:",fileinfo.filename,"basename:",fileinfo.basename,"extname:",fileinfo.extname)
    --     local fileStr = io.readStream(fileName, 0, filelen)
    --     log.info("testFs.readStream val:",fileStr)
    -- else
    --     log.info("testFs ca file is not exists, creating file...")
    --     io.writeFile(fileName,tostring(cacert))
    -- end
end

local function downloadServerCACbFnc(result, prompt, head, body)

    log.info("testHttp.cbFnc-downloadServerCACbFnc", result, prompt)
    if result and head then
        for k, v in pairs(head) do
            log.info("testHttp.cbFnc", k .. ": " .. v)
        end
    end
    if result and body then
        -- log.info("testHttp.cbFnc","bodyLen="..body:len())
        -- log.info("body:", body)
        -- log.info("body type:",type(body))
        local tjsondata, resultBody, errinfo = json.decode(body)
        -- log.info("tjsondata_result", resultBody)
        -- log.info("tjsondata_rrinfo", errinfo)
        -- log.info("tjsondata:",tjsondata,"type of tjsondata:",type(tjsondata))

        local cadata = tjsondata["cert"]
        log.info("get ca data done", cadata)
        if cadata ~= "" then
            ServerCA = cadata
            log.info("ca data:", ServerCA)
            saveServerCA(cadata)
            sys.publish("GET_CA_DONE")
        end

    end
end

local function downloadServerCA() --TODOupdate down ca from server
    -- 222.128.62.153
    local base = authServer -- "http://120.205.5.245:28003/"  --http://202.99.246.78:8888/
    local url = base .. "/api/v1/signcert"
    log.info("request url=", url)
    -- 次数限制

    log.info("get ServerCA.")
    local resp = http.request("GET", url, nil, nil, nil, 30000,
                              downloadServerCACbFnc);
    sys.waitUntil("GET_CA_DONE", 3000)
    log.info("http get resp:", resp);
    log.info("ServerCA is:", ServerCA);

    sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                os.date("*t").year, os.date("*t").month,
                                os.date("*t").day, os.date("*t").hour,
                                os.date("*t").min, os.date("*t").sec)

    logInfo = "[" .. sysTime .. "]" .."[Downloaded ServerCA is:"..ServerCA.."]\n"
    logGenerator.generateLogTask(logInfo, "log")

    -- if ServerCA~="" then
    --     log.info("ServerCA File Content",ServerCA)

    -- end

    -- saveServerCA()
end
-- downloadServerCA()



local function getServerCA()
    local cacert
    local fileName = fileServerCA
    if io.exists(fileName) then
        local fileval = io.readFile(fileName)
        -- log.info("testFs.readFile ",fileval)
        local filelen = io.fileSize(fileName)
        -- log.info("testFs.fileSize ",filelen)
        local fileinfo = io.pathInfo(fileName)
        -- log.info("testFs.pathInfo","dirname:",fileinfo.dirname,"filename:",fileinfo.filename,"basename:",fileinfo.basename,"extname:",fileinfo.extname)
        local fileStr = io.readStream(fileName, 0, filelen)
        -- log.info("testFs.readStream serverCA val:",fileStr)
        return fileStr
    else
        log.info("Pls make sure file serverCA existing...")
        sys.taskInit(downloadServerCA)
        return nil
        -- if ServerCA~="" then
        --     return ServerCA

        -- end
    end
end
-- getServerCA()

local function judgeAuthServer()
    if previousAuthServer ~= authServer  then
        log.info("authServer para get updated!")
        local cadata=""
        saveServerCA(cadata)
        previousAuthServer = authServer
        nvm.sett("securityConfig", 10, tostring(previousAuthServer), "SVR")
        sys.taskInit(downloadServerCA)
    end
end
judgeAuthServer()

local function getOfficialCA()
    local cacert
    local fileName = fileOfficialCA
    if io.exists(fileName) then
        local fileval = io.readFile(fileName)
        -- log.info("testFs.readFile officialCA",fileval)
        local filelen = io.fileSize(fileName)
        -- log.info("testFs.fileSize ",filelen)
        local fileinfo = io.pathInfo(fileName)
        -- log.info("testFs.pathInfo","dirname:",fileinfo.dirname,"filename:",fileinfo.filename,"basename:",fileinfo.basename,"extname:",fileinfo.extname)
        local fileStr = io.readStream(fileName, 0, filelen)
        -- log.info("testFs.readStream officialCA val:",fileStr)
        return fileStr
    else
        log.info("Pls make sure file existing...")
        return nil
    end
end
-- getOfficialCA()

local function convertMsgFormat(inMsg)
    local outMsg = ""
    local list = {}
    local length = 0
    local key, value
    for k, v in pairs(inMsg) do
        length = length + 1
        print(k, v)
        list[length] = k
    end

    table.sort(list)

    -- 打印排序后的数组
    for i = 1, #list do
        key = list[i]
        value = inMsg[list[i]]
        print("print key value:", key, value)

        if "5" == key or 5 == key then
            log.info("ignore key signature:", i, key, value)
        else
            if i == #list then
                log.info("postion of last value:", i, key, value)
                outMsg = outMsg .. key .. "=" .. value
            else
                log.info("other element:", i, key, value)
                outMsg = outMsg .. key .. "=" .. value .. "&"
            end

        end

    end

    return outMsg
end

local function getSignature(inMsg)

    local signature = ""
    for k, v in pairs(inMsg) do
        -- size = size + 1
        if k == 5 or k == "5" then signature = tostring(v) end
    end

    return signature
end
--[[ local function verifyMessage()
    local message
    local cacert = getServerCA()
    -- log.info("server ca content1:",cacert)
    if cacert==nil or cacert=="" then
        downloadServerCA()
        cacert = getServerCA()
    end
    log.info("server ca content:",cacert)

    local cert=getOfficialCA()
    log.info("official ca content:",cert)


    -- local message='{"1":"exercise.1715852349546_1","2":"0201","3":"2024-05-16 17:39:19.023","4":"null","6":"2.0","7":"exercise.1715852349546","8":"1","9":"CB","10":"UID:9yzwfM499890569978869Kt89hy1L855","11":"blue","12":"2024-05-16 17:39:19.023","13":"(演练)测试","14":"0.0","15":"0.0","16":"0","17":"0.0","18":"0.0","5":"MEUCIQCNQfktxRvCJkuCd0thX1HyaXwbsjG+J8hvIaIjMUsPDQIgPRmbSexlr7JLK26ZE6CiaNoEBuIVcjfHagskJ6p0QRQ=|rQu2nSZEKADmdaqSh3jMYYbJmOE="}'
    -- if EarthQuakeMessage~=nil and EarthQuakeMessage~={} then
    --     message=EarthQuakeMessage
    -- end

    message=mqttInMsgQuakeInfoRel.EarthQuakeMessage

    log.info("type of message:",type(message),message,message["1"],message["10"],message["11"])
    local tjsondata, resultMqtt, errinfo = json.decode(message)
    log.info("type of tjsondata111:",type(tjsondata),tjsondata["1"],tjsondata["2"],tjsondata["3"],tjsondata["7"])
    -- local msg=convertMsgFormat(tjsondata)
    local msg=""
    local sig=""
    if message~="" then
        msg=convertMsgFormat(message)
        sig=getSignature(message)
    end

    -- local msg=generateSignString(tjsondata)

    log.info("converted msg type:",type(msg))
    log.info("converted msg:",msg)
    log.info("get signature:",sig)

    -- local msg =
    --     "1=20240330093309_1&10=UID:1231242&11=blue&12=2024-03-30 09:33:09.731&13=测试地点&14=0.000&15=0.000&16=10&17=1.0&18=1&2=0301&3=2024-03-30 09:33:09.767&4=CB&6=1.0&7=20240330093309&8=1&9=CB"

    -- local sig =
    --     "MEUCIBCxa9jIVB1mmeBaMfEMH61juMdkRHb9rTkxeSQWG/xAAiEA+Dd1LW+COkVU1CGl3ZzaBPP7mmhW4bu8XWZrtybkd7Y=|rQu2nSZEKADmdaqSh3jMYYbJmOE="
    -- local cert =
        -- "MIIEaDCCBA2gAwIBAgIKGhAAAAAABBVJdDAKBggqgRzPVQGDdTBEMQswCQYDVQQGEwJDTjENMAsGA1UECgwEQkpDQTENMAsGA1UECwwEQkpDQTEXMBUGA1UEAwwOQmVpamluZyBTTTIgQ0EwHhcNMjMxMjEzMTYwMDAwWhcNMzMwMTEwMTU1OTU5WjBeMRswGQYDVQQpDBIxMjEwMDAwMDAwMDAxNDE5N1ExGDAWBgNVBAMMD+WbveWutuWcsOmch+WxgDEYMBYGA1UECgwP5Zu95a625Zyw6ZyH5bGAMQswCQYDVQQGDAJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNbtODPdgnITR54Kf7uJXYFe8YJ57brTqHA2NEJJbH5h6OohsNmkGXr+8TwBABWRaJ2zg856QDAko/DkrFydPOyjggLLMIICxzAfBgNVHSMEGDAWgBQf5s/Uj8UiKpdKKYoV5xbJkjTEtjAdBgNVHQ4EFgQUi2vkYZqRfxehcAAornQwh8+NM7kwgZ8GA1UdHwSBlzCBlDBhoF+gXaRbMFkxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDARCSkNBMQ0wCwYDVQQLDARCSkNBMRcwFQYDVQQDDA5CZWlqaW5nIFNNMiBDQTETMBEGA1UEAxMKY2EyMWNybDM0NjAvoC2gK4YpaHR0cDovL2NybC5iamNhLm9yZy5jbi9jcmwvY2EyMWNybDM0Ni5jcmwwJAYKKoEchu8yAgEBAQQWDBRKSjEyMTAwMDAwMDAwMDE0MTk3UTBgBggrBgEFBQcBAQRUMFIwIwYIKwYBBQUHMAGGF09DU1A6Ly9vY3NwLmJqY2Eub3JnLmNuMCsGCCsGAQUFBzAChh9odHRwOi8vY3JsLmJqY2Eub3JnLmNuL2NhaXNzdWVyMEAGA1UdIAQ5MDcwNQYJKoEchu8yAgIBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuYmpjYS5vcmcuY24vY3BzMBEGCWCGSAGG+EIBAQQEAwIA/zAiBgoqgRyG7zICAQEIBBQMEjEyMTAwMDAwMDAwMDE0MTk3UTAkBgoqgRyG7zICAQICBBYMFEpKMTIxMDAwMDAwMDAwMTQxOTdRMB8GCiqBHIbvMgIBAQ4EEQwPMTAyMDgwMDM2OTI5MjY2MCQGCiqBHIbvMgIBAQQEFgwUSkoxMjEwMDAwMDAwMDAxNDE5N1EwLgYKKoEchu8yAgEBFwQgDB4yNEAyMTUwMDlKSjAxMjEwMDAwMDAwMDAxNDE5N1EwIAYIKoEc0BQEAQQEFAwSMTIxMDAwMDAwMDAwMTQxOTdRMBMGCiqBHIbvMgIBAR4EBQwDNjU0MA4GA1UdDwEB/wQEAwIGwDAKBggqgRzPVQGDdQNJADBGAiEA9G5vMUNhyOmRyntGayM+VlB0SCRevgp3uVJFngSXsxkCIQDQdTzr4rwzYqNnqPUTIUHHUgtUFruRY4fN8AEtY5ifKw=="

    if msg~="" and sig~="" and cert~="" and cacert~="" and cacert~=nil then
        local ret = dzjkxc.verify_message(msg, sig, cacert, cert)
        print("VerifyMessage: ret = ", ret)

        sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                            os.date("*t").year,
                                            os.date("*t").month,
                                            os.date("*t").day,
                                            os.date("*t").hour,
                                            os.date("*t").min, os.date("*t").sec)
        if ret=="1" or ret==1 then
            log.info("verify message pass.")
            logInfo = "[" .. sysTime .. "]" ..
                                            "[验签成功，验证消息成功！]\n"
                            logGenerator.generateLogTask(logInfo, "log")
            message= ""
            mqttInMsgQuakeInfoRel.EarthQuakeMessage = {}
            return true
        elseif ret=="0" or ret==0 then
            log.info("verify message incomplete.")
            logInfo = "[" .. sysTime .. "]" ..
                                            "[验签失败，验证消息不完整！]\n"
                            logGenerator.generateLogTask(logInfo, "log")
            message= ""
            mqttInMsgQuakeInfoRel.EarthQuakeMessage = {}
            return false
        else
            log.info("verify message fail.")
            logInfo = "[" .. sysTime .. "]" ..
                                            "[验签失败，其他错误！]\n"
                            logGenerator.generateLogTask(logInfo, "log")
            message= ""
            mqttInMsgQuakeInfoRel.EarthQuakeMessage = {}
            return false
        end
    end



end ]]
function VerifyMessage(message)
    local cacert = getServerCA()
    -- log.info("server ca content1:",cacert)
    if cacert == nil or cacert == "" then
        sys.taskInit(downloadServerCA)
        cacert = getServerCA()
    end
    log.info("server ca content:", cacert)
    sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                os.date("*t").year, os.date("*t").month,
                                os.date("*t").day, os.date("*t").hour,
                                os.date("*t").min, os.date("*t").sec)

    logInfo = "[" .. sysTime .. "]" .."[Verify message using ServerCA is:"..cacert.."]\n"
    logGenerator.generateLogTask(logInfo, "log")

    local cert = getOfficialCA()
    -- log.info("official ca content:", cert)
    logInfo = "[" .. sysTime .. "]" .."[Verify message using official ca content is:"..cert.."]\n"
    logGenerator.generateLogTask(logInfo, "log")
    -- local message='{"1":"exercise.1715852349546_1","2":"0201","3":"2024-05-16 17:39:19.023","4":"null","6":"2.0","7":"exercise.1715852349546","8":"1","9":"CB","10":"UID:9yzwfM499890569978869Kt89hy1L855","11":"blue","12":"2024-05-16 17:39:19.023","13":"(演练)测试","14":"0.0","15":"0.0","16":"0","17":"0.0","18":"0.0","5":"MEUCIQCNQfktxRvCJkuCd0thX1HyaXwbsjG+J8hvIaIjMUsPDQIgPRmbSexlr7JLK26ZE6CiaNoEBuIVcjfHagskJ6p0QRQ=|rQu2nSZEKADmdaqSh3jMYYbJmOE="}'
    -- if EarthQuakeMessage~=nil and EarthQuakeMessage~={} then
    --     message=EarthQuakeMessage
    -- end
    log.info("type of message:", type(message), message, message["1"],
             message["10"], message["11"])
    local tjsondata, resultMqtt, errinfo = json.decode(message)
    log.info("type of tjsondata111:", type(tjsondata), tjsondata["1"],
             tjsondata["2"], tjsondata["3"], tjsondata["7"])
    -- local msg=convertMsgFormat(tjsondata)
    local msg = ""
    local sig = ""
    if message ~= "" then
        msg = convertMsgFormat(message)
        sig = getSignature(message)
    end

    -- local msg=generateSignString(tjsondata)

    log.info("converted msg type:", type(msg))
    log.info("converted msg:", msg)
    log.info("get signature:", sig)

    -- local msg =
    --     "1=20240330093309_1&10=UID:1231242&11=blue&12=2024-03-30 09:33:09.731&13=测试地点&14=0.000&15=0.000&16=10&17=1.0&18=1&2=0301&3=2024-03-30 09:33:09.767&4=CB&6=1.0&7=20240330093309&8=1&9=CB"

    -- local sig =
    --     "MEUCIBCxa9jIVB1mmeBaMfEMH61juMdkRHb9rTkxeSQWG/xAAiEA+Dd1LW+COkVU1CGl3ZzaBPP7mmhW4bu8XWZrtybkd7Y=|rQu2nSZEKADmdaqSh3jMYYbJmOE="
    -- local cert =
    -- "MIIEaDCCBA2gAwIBAgIKGhAAAAAABBVJdDAKBggqgRzPVQGDdTBEMQswCQYDVQQGEwJDTjENMAsGA1UECgwEQkpDQTENMAsGA1UECwwEQkpDQTEXMBUGA1UEAwwOQmVpamluZyBTTTIgQ0EwHhcNMjMxMjEzMTYwMDAwWhcNMzMwMTEwMTU1OTU5WjBeMRswGQYDVQQpDBIxMjEwMDAwMDAwMDAxNDE5N1ExGDAWBgNVBAMMD+WbveWutuWcsOmch+WxgDEYMBYGA1UECgwP5Zu95a625Zyw6ZyH5bGAMQswCQYDVQQGDAJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNbtODPdgnITR54Kf7uJXYFe8YJ57brTqHA2NEJJbH5h6OohsNmkGXr+8TwBABWRaJ2zg856QDAko/DkrFydPOyjggLLMIICxzAfBgNVHSMEGDAWgBQf5s/Uj8UiKpdKKYoV5xbJkjTEtjAdBgNVHQ4EFgQUi2vkYZqRfxehcAAornQwh8+NM7kwgZ8GA1UdHwSBlzCBlDBhoF+gXaRbMFkxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDARCSkNBMQ0wCwYDVQQLDARCSkNBMRcwFQYDVQQDDA5CZWlqaW5nIFNNMiBDQTETMBEGA1UEAxMKY2EyMWNybDM0NjAvoC2gK4YpaHR0cDovL2NybC5iamNhLm9yZy5jbi9jcmwvY2EyMWNybDM0Ni5jcmwwJAYKKoEchu8yAgEBAQQWDBRKSjEyMTAwMDAwMDAwMDE0MTk3UTBgBggrBgEFBQcBAQRUMFIwIwYIKwYBBQUHMAGGF09DU1A6Ly9vY3NwLmJqY2Eub3JnLmNuMCsGCCsGAQUFBzAChh9odHRwOi8vY3JsLmJqY2Eub3JnLmNuL2NhaXNzdWVyMEAGA1UdIAQ5MDcwNQYJKoEchu8yAgIBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuYmpjYS5vcmcuY24vY3BzMBEGCWCGSAGG+EIBAQQEAwIA/zAiBgoqgRyG7zICAQEIBBQMEjEyMTAwMDAwMDAwMDE0MTk3UTAkBgoqgRyG7zICAQICBBYMFEpKMTIxMDAwMDAwMDAwMTQxOTdRMB8GCiqBHIbvMgIBAQ4EEQwPMTAyMDgwMDM2OTI5MjY2MCQGCiqBHIbvMgIBAQQEFgwUSkoxMjEwMDAwMDAwMDAxNDE5N1EwLgYKKoEchu8yAgEBFwQgDB4yNEAyMTUwMDlKSjAxMjEwMDAwMDAwMDAxNDE5N1EwIAYIKoEc0BQEAQQEFAwSMTIxMDAwMDAwMDAwMTQxOTdRMBMGCiqBHIbvMgIBAR4EBQwDNjU0MA4GA1UdDwEB/wQEAwIGwDAKBggqgRzPVQGDdQNJADBGAiEA9G5vMUNhyOmRyntGayM+VlB0SCRevgp3uVJFngSXsxkCIQDQdTzr4rwzYqNnqPUTIUHHUgtUFruRY4fN8AEtY5ifKw=="

    if msg ~= "" and cert ~= "" and cacert ~= "" and cacert ~= nil then
        if sig ~= "" and sig~=nil then
            local ret = dzjkxc.verify_message(msg, sig, cacert, cert)
            print("VerifyMessage: ret = ", ret)

            sysTime = string.format("%04d-%02d-%02d %02d:%02d:%02d",
                                    os.date("*t").year, os.date("*t").month,
                                    os.date("*t").day, os.date("*t").hour,
                                    os.date("*t").min, os.date("*t").sec)
            if ret == "1" or ret == 1 then
                log.info("verify message pass.")
                logInfo = "[" .. sysTime .. "]" ..
                              "[验签成功，验证消息成功！]\n"
                logGenerator.generateLogTask(logInfo, "log")
                return true, "验签成功"
            elseif ret == "0" or ret == 0 then
                log.info("verify message incomplete.")
                logInfo = "[" .. sysTime .. "]" ..
                              "[验签失败，验证消息不完整！]\n"
                logGenerator.generateLogTask(logInfo, "log")
                return false, "验签失败，验证消息不完整！"
            else
                log.info("verify message fail.")
                logInfo = "[" .. sysTime .. "]" ..
                              "[验签失败，其他错误！]\n"
                logGenerator.generateLogTask(logInfo, "log")
                return false, "验签失败，其他错误！"
            end
        else
            log.info("para signature is nil.")
                logInfo = "[" .. sysTime .. "]" ..
                              "[验签失败，签名为nil或者空字符串！]\n"
                logGenerator.generateLogTask(logInfo, "log")
                return false, "验签失败，签名为nil或者空字符串！"
        end



    end
end

local function verifyServerCA()
    local cacert = getServerCA()
    --log.info("server ca content1:",cacert)
    if cacert == nil or cacert == "" then
        sys.taskInit(downloadServerCA)
        cacert = getServerCA()
    end
    --log.info("server ca content in verifyServerCA:", cacert)
end

function split(input, delimiter)
    if type(delimiter) ~= "string" or #delimiter <= 0 then
        return
    end
    local start = 1
    local arr = {}
    while true do
        local pos = string.find(input, delimiter, start, true)
        if not pos then
            break
        end
        table.insert (arr, string.sub (input, start, pos - 1))
        start = pos + string.len (delimiter)
    end
    table.insert (arr, string.sub (input, start))
    return arr
end

-- 常规测试
sys.taskInit(function()

    if handle then
        while true do
            -- local handler = io.popen("ping -c 3 -i 0.5 47.94.80.3")
            -- local response = handler:read("*a")
            -- http.request("GET","https://api-sit.isignet.cn:8082/cert/v2",nil,nil,nil,nil,cbFnc)

            -- local key= "y0pwdw6IqvXV7yQmJSqVyDVrJnfeZ9RA"

            --print("#################################################################")

            -- serverIsIP()

            if FlagUseToken == true then
                verifyServerCA()   --不能删掉，所有做http请求的操作要放在循环里处理，确保http请求成功
                sys.waitUntil("TOKEN_TRIED", 3000)
                log.info("FlagMqttConnect:", FlagMqttConnect,
                         "type of FlagMqttConnect", type(FlagMqttConnect))
                -- FlagMqttConnect = stringToBool(nvm.get("securityConfig")[7])
                -- TokenData = nvm.get("securityConfig")[5]
                if FlagMqttConnect == false or FlagMqttConnect == nil then
                    log.info("refresh token.")
                    sys.waitUntil("TOKEN_LOGIN_TRIED_FAIL", 3000)
                    nvm.sett("securityConfig", 5, tostring(""), "SVR") -- 清除token
                    TokenData = nvm.get("securityConfig")[5]
                    log.info("token data is111:", TokenData)
                    -- refreshToken()
                    -- FlagMqttConnect=true  --in case new token generated
                    -- sys.waitUntil("GENERATE_TOKEN_DONE",3000)
                    -- sys.wait(3000)
                else
                    log.info("token is valid!")
                end

                -- TokenData = nvm.get("securityConfig")[5]
                if TokenData == "" and connect_times < maxConnectTimes then -- 判断更新token次数
                    connect_times = connect_times + 1
                    -- reqMarkCert()
                    refreshToken()
                    -- sys.wait(3000)
                    sys.waitUntil("GENERATE_TOKEN_DONE", 3000)
                    FlagMqttConnect = true -- in case new token generated
                    -- nvm.sett("securityConfig", 7, tostring(FlagMqttConnect),"SVR")
                    log.info("request token in progress")
                elseif TokenData == "" and connect_times >= maxConnectTimes then
                    log.info("request token failed")
                    -- nvm.sett("securityConfig", 1, tostring(""), "SVR")
                    -- nvm.sett("securityConfig", 3, tostring(""), "SVR")
                    -- nvm.sett("securityConfig", 5, tostring(""), "SVR")
                    -- nvm.sett("securityConfig", 8, tostring(""), "SVR")
                else
                    log.info("request token success!")
                    FlagMqttConnect = true

                    -- nvm.sett("securityConfig", 7, tostring(FlagMqttConnect),"SVR")
                end

                -- verifyMessage()
            end

            -- if FlagMqttConnect==true then
            --     local topic = "testmqtt"
            --     local sendMsg = "test hello mqtt"
            --     mqttOutMsg.insertMsg(topic, sendMsg, 0)
            --     log.info("publish mqtt message testmqtt")
            -- end
            -- updateMarkCert()
            -- local mck_server = "222.128.62.153"
            -- local mck_port = 19527
            -- local mck_appid = "XZGw9Vcbeb389c43ca47"
            -- local mck_appsecret =
            --     "6bd37a9c91dd45ae90a4ab51f00c04ecd93cb46dcaf649709d48023a35dbdaba"
            -- local ret = dzjkxc.set_mck_conf(mck_server, mck_port, mck_appid,
            --                                 mck_appsecret)
            -- print("SetMckConf: ret = ", ret)
            -- local data, key
            -- data, key, ret = dzjkxc.get_key("", "fakedeviceserial")
            -- print("GetKey: data = ", data)
            -- print("        key = ", key)
            -- print("        ret = ", ret)
            -- local msg =
            --     "1=20240330093309_1&10=UID:1231242&11=blue&12=2024-03-30 09:33:09.731&13=测试地点&14=0.000&15=0.000&16=10&17=1.0&18=1&2=0301&3=2024-03-30 09:33:09.767&4=CB&6=1.0&7=20240330093309&8=1&9=CB"
            -- local sig =
            --     "MEYCIQCgSlOsAKaeTpfk/v7mN+87UjPjKuBlIHwiz51Eggqq7QIhAJcz2gzSq0VG2xi1WTTUtbzgaeeP8RSww2WHhQ3kd6go|i2vkYZqRfxehcAAornQwh8+NM7k="
            -- local cert =
            --     "MIIEaDCCBA2gAwIBAgIKGhAAAAAABBVJdDAKBggqgRzPVQGDdTBEMQswCQYDVQQGEwJDTjENMAsGA1UECgwEQkpDQTENMAsGA1UECwwEQkpDQTEXMBUGA1UEAwwOQmVpamluZyBTTTIgQ0EwHhcNMjMxMjEzMTYwMDAwWhcNMzMwMTEwMTU1OTU5WjBeMRswGQYDVQQpDBIxMjEwMDAwMDAwMDAxNDE5N1ExGDAWBgNVBAMMD+WbveWutuWcsOmch+WxgDEYMBYGA1UECgwP5Zu95a625Zyw6ZyH5bGAMQswCQYDVQQGDAJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNbtODPdgnITR54Kf7uJXYFe8YJ57brTqHA2NEJJbH5h6OohsNmkGXr+8TwBABWRaJ2zg856QDAko/DkrFydPOyjggLLMIICxzAfBgNVHSMEGDAWgBQf5s/Uj8UiKpdKKYoV5xbJkjTEtjAdBgNVHQ4EFgQUi2vkYZqRfxehcAAornQwh8+NM7kwgZ8GA1UdHwSBlzCBlDBhoF+gXaRbMFkxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDARCSkNBMQ0wCwYDVQQLDARCSkNBMRcwFQYDVQQDDA5CZWlqaW5nIFNNMiBDQTETMBEGA1UEAxMKY2EyMWNybDM0NjAvoC2gK4YpaHR0cDovL2NybC5iamNhLm9yZy5jbi9jcmwvY2EyMWNybDM0Ni5jcmwwJAYKKoEchu8yAgEBAQQWDBRKSjEyMTAwMDAwMDAwMDE0MTk3UTBgBggrBgEFBQcBAQRUMFIwIwYIKwYBBQUHMAGGF09DU1A6Ly9vY3NwLmJqY2Eub3JnLmNuMCsGCCsGAQUFBzAChh9odHRwOi8vY3JsLmJqY2Eub3JnLmNuL2NhaXNzdWVyMEAGA1UdIAQ5MDcwNQYJKoEchu8yAgIBMCgwJgYIKwYBBQUHAgEWGmh0dHA6Ly93d3cuYmpjYS5vcmcuY24vY3BzMBEGCWCGSAGG+EIBAQQEAwIA/zAiBgoqgRyG7zICAQEIBBQMEjEyMTAwMDAwMDAwMDE0MTk3UTAkBgoqgRyG7zICAQICBBYMFEpKMTIxMDAwMDAwMDAwMTQxOTdRMB8GCiqBHIbvMgIBAQ4EEQwPMTAyMDgwMDM2OTI5MjY2MCQGCiqBHIbvMgIBAQQEFgwUSkoxMjEwMDAwMDAwMDAxNDE5N1EwLgYKKoEchu8yAgEBFwQgDB4yNEAyMTUwMDlKSjAxMjEwMDAwMDAwMDAxNDE5N1EwIAYIKoEc0BQEAQQEFAwSMTIxMDAwMDAwMDAwMTQxOTdRMBMGCiqBHIbvMgIBAR4EBQwDNjU0MA4GA1UdDwEB/wQEAwIGwDAKBggqgRzPVQGDdQNJADBGAiEA9G5vMUNhyOmRyntGayM+VlB0SCRevgp3uVJFngSXsxkCIQDQdTzr4rwzYqNnqPUTIUHHUgtUFruRY4fN8AEtY5ifKw=="
            -- local cacert =
            --     "MIIClzCCAjygAwIBAgIQdd/IVUqMA6s1z1nouGE7njAMBggqgRzPVQGDdQUAMC4xCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEPMA0GA1UEAwwGUk9PVENBMB4XDTEzMDExNjExMDczMVoXDTMzMDExMTExMDczMVowRDELMAkGA1UEBhMCQ04xDTALBgNVBAoMBEJKQ0ExDTALBgNVBAsMBEJKQ0ExFzAVBgNVBAMMDkJlaWppbmcgU00yIENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEioqqRw0qmjPYUF+6SWgWI1JzDHPGO0iTjSa5m0MuR/QB83yLBknccZ3T1qwdgv27e3qqKMdA3U3ipZkz6qxVk6OCASIwggEeMB8GA1UdIwQYMBaAFEwysZfZMxvEpgXBxuWLYlvwl3ZYMA8GA1UdEwEB/wQFMAMBAf8wgboGA1UdHwSBsjCBrzBBoD+gPaQ7MDkxCzAJBgNVBAYTAkNOMQ4wDAYDVQQKDAVOUkNBQzEMMAoGA1UECwwDQVJMMQwwCgYDVQQDDANhcmwwKqAooCaGJGh0dHA6Ly93d3cucm9vdGNhLmdvdi5jbi9hcmwvYXJsLmNybDA+oDygOoY4bGRhcDovL2xkYXAucm9vdGNhLmdvdi5jbjozODkvQ049YXJsLE9VPUFSTCxPPU5SQ0FDLEM9Q04wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQf5s/Uj8UiKpdKKYoV5xbJkjTEtjAMBggqgRzPVQGDdQUAA0cAMEQCIFiMoH1BR7I3DmlPk5uhui/W2cX6iPAdnXI4LSPUg9T9AiB06XDp+wsPScMBYzRuY5xBC7IiC+nj+ehMDmkLD4mXKg=="
            -- ret = dzjkxc.verify_message(msg, sig, cert, cacert)
            -- print("VerifyMessage: ret = ", ret)
            -- print("---------------------")
            -- local csr, ret = dzjkxc.generate_csr(key, "device_clientid",
            --                                     "device_username")
            -- print("GenerateCsr: ret = ", ret)
            -- print("GenerateCsr: csr = ", csr)
            -- -- 使用csr准备设备证书
            -- local deviceCert = cert
            -- local rt=os.time()
            -- log.info("time stamp is:",rt)
            -- local token, ret = dzjkxc.generate_token(key, rt,
            --                                         "222.128.62.153", deviceCert)

            -- print("GenerateToken: token = ", token)
            -- print("GenerateToken: ret = ", ret)

            -- mac, rv = dzjkxc.hmac_sha256_b64("message", "secret") --返回的mac已经做了base64编码，message和secret都是字符串形式，不经过base64编码
            -- log.info("mac:",mac,"rv:",rv)

            -- local myTable = { foo = "bar", baz = "qux" }
            -- local jsonString = tableToJson(myTable)
            -- log.info("jsonString:",jsonString)

            --log.info("Mem Used Size KB:", collectgarbage("count"),",Mem Free Size KB:", 1360 - collectgarbage("count"))

            sys.wait(3000)
        end
    end
end)

-- -- 创建对象
-- myshape = Shape:new(nil,10)
-- myshape:printArea()

-- -- 创建对象
-- mysquare = Square:new(nil,10)
-- mysquare:printArea()

-- -- 创建对象
-- myrectangle = Rectangle:new(nil,10,20)
-- myrectangle:printArea()

